<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <div id="app"></div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://wzrd.in/standalone/path-to-regexp"></script>
  <script>
    const Foo = {
      props: ['id'],
      template: `<div>foo with id: {{ id }}</div>`
    };
    const Bar = { template: `<div>bar</div>` };
    const NotFound = { template: '<div>not found!</div>' };

    const routeTable = {
      '/foo/:id': Foo,
      '/bar': Bar
    };

    const compiledRoutes = [];
    Object.keys(routeTable).forEach(path => {
      const dynamicSegments = [];
      const regex = pathToRegexp(path, dynamicSegments);
      const component = routeTable[path];
      compiledRoutes.push({
        component,
        regex,
        dynamicSegments
      });
    });


    window.addEventListener('hashchange', () => {
      app.url = window.location.hash.slice(1);
    });

    const app = new Vue({
      el: '#app',
      data: {
        url: window.location.hash.slice(1)
      },
      render(h) {
        const path = '/' + this.url;

        let componentToRender;
        let props = {};
        compiledRoutes.some(route => {
          const match = route.regex.exec(path);
          if (match) {
            componentToRender = route.component;
            route.dynamicSegments.forEach((segment, index) => {
              props[segment.name] = match[index + 1];
            });
            return true;
          }
        });

        return h('div', [
          h(componentToRender || NotFound, { props }),
          h('a', { attrs: { href: '#foo/123' } }, 'foo 123'),
          ' ',
          h('a', { attrs: { href: '#foo/234' } }, 'foo 234'),
          ' ',
          h('a', { attrs: { href: '#bar' } }, 'bar')
        ]);
      }
    });
  </script>
</body>
</html>